home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok22.lha
/
MakeKickRes
/
ResetFest.dok
< prev
next >
Wrap
Text File
|
1993-08-15
|
5KB
|
132 lines
RESETFEST - WIE GEHT'S ??? (von Holger Gzella)
**************************
Für manche Anwendungen ist es einfach notwendig, Programme resetfest zu
machen (siehe TURBOPRINT, RAD: etc.). Da gibt es auf dem Amiga zwei Mög-
lichkeiten:
a) Die einfache Methode über die Capture-Vektoren
b) Die kompliziertere Methode über Resident-Module
Ersteres wurde schon häufig besprochen und ist auch nicht für alle Sachen
sinnvoll, da, wenn der CoolCapture-Vektor angesprungen wird, lediglich die
Exec-Library initialisiert ist. Nutzt man aber Resident-Module, so ist das
System zum Zeitpunkt des Aufrufes schon fast hochgefahren. So sind z.B.
Graphics und Intuition initialisiert, das Fast-Memory ist da, usw.
In diesem Text soll gezeigt werden, wie Resident-Module selbst geschrieben
werden. Als Demoprogramm dient MakeKickRes.
Zuerst muß eine Speicherliste initialisiert werden. Diese muß Platz für
soviele Einträge, wie eigene Resident-Module bieten. In diesem Fall ge-
he ich davon aus, daß nur ein Resident-Modul initialisiert werden soll.
Folgende Liste muß definiert werden:
NewMemList=RECORD
node : Node; (* Node - wichtig für alle Listen *)
numEntries: CARDINAL; (* Anzahl der Einträge - hier 4 *)
me : ARRAY[0..3] OF MemEntry; (* 4 Listeneinträge *)
END;
Warum für ein resetfestes Programm vier Einträge benötigt werden, wird noch
erklärt.
Der nächste Record, der definiert werden muß, besteht aus zwei Adressen:
PtrTable=RECORD
adr1: ADDRESS; (* Wozu das gut ist, kommt noch! *)
adr2: ADDRESS;
END;
Diese Liste muß nun angepaßt werden. So schreibe man nun in das Feld
numEntries die Zahl 4 und als Nodentyp in das Feld MyMemList.node.type den
Wert memory aus der NodeType-Aufzählung.
Nun muß der Code des Programms, das resetfest gemacht werden soll, in einen
mit AllocMem() zur Verfügung gestellten Speicherbereich (chip,memClear und
public) kopiert werden. Der Code MUSS PC-relativ assembliert sein. Daher
ist es leider noch(!) nicht möglich, Modula-Programme zu verankern.
Als nächsten Schritt muß man eine Resident-Struktur, die in Exec definiert
ist, patchen. In das Feld matchWord kommt die Konstante matchword, in das
Feld matchTag ein Zeiger auf die Resident-Struktur selbst, in das Feld
endSkip die Adresse des Endes des Resident-Records. In Flags sollte man
coldstart (aus ResidentFlagSet) schreiben, da es sich um ein Programm han-
delt, was wir hier speicherfest machen wollen. Möchte man eine Library resi-
dent verankern, muß man autoinit eintragen. Nun muß man die Priorität des
eigenen Programms im Feld pri festlegen. Das Resident-Modul mit der höch-
sten Priorität wird zuerst ausgeführt. Ich empfehle hier -1 oder -2, denn
wird der Wert kleiner oder gleich -60, wird das Programm nicht mehr aus-
geführt, sondern sofort der Bootvorgang gestartet. Die Adresse des Codes
(die wir von AllocMem() bekommen haben) muß in das Feld init eingetragen
werden.
Jetzt ist die Adresse des resetfesten Codes noch in das Feld MyMemList.me[0].
addr und die Länge in MyMemList.me[0].length einzutragen. Das war der erste
MemList-Eintrag.
Als zweiten MemList-Eintrag müssen wir den Resident-Record nehmen:
MyMemList.me[1].addr:=ADR(MyResident) (z.B.)
MyMemList.me[1].length:=SIZE(Resident)
Der nächste Schritt ist, daß die Adresse des Resident-Records in das Feld
MyPtrTable.adr1 geschrieben werden muß.
Nun muß der PtrTable-Record (bzw. ein Zeiger darauf) als dritter Eintrag
in die MemList:
MyMemList.me[2].addr:=ADR(MyPtrTable) (z.B.)
MyMemList.me[2].length:=8 (2 Longwords=8 Bytes)
Der vierte Eintrag der MemList muß ein Zeiger auf die MemList selbst sein:
MyMemList.me[3].addr:=ADR(MyMemList)
MyMemList.me[3].length:=SIZE(NewMemList)
Nun muß man die Adresse der MemList in den ExecBase-Zeiger KickMemPtr
eintragen:
execBase^.kickMemPtr:=ADR(MyMemList);
In den ExecBase-Zeiger KickTagPtr kommt die Adresse der zwei Zeiger:
execBase^.kickTagPtr:=ADR(MyPtrTable);
Jetzt muß noch die Resident-Prüfsumme berechnet werden. Da tut sich ein
Problem auf: das Exec-Definitionsmodul ist da fehlerhaft! Die Funktion
SumKickData() liefert einen LONGINT-Wert zurück! Kein Problem, ein ge-
patchtes Exec.def befindet sich in diesem Directory. Also:
MyCheckSum:=SumKickData();
Und nun noch die Checksumme eintragen:
execBase^.kickCheckSum:=MyCheckSum;
***** FERTIG! *****
Beim nächsten Reset wird dann, sofern der Code O.K. ist, das resetfeste
Maschinenprogramm ausgeführt.
Man kann also mit DevPac oder Profimat oder sonst einem Assembler ein
Programm PC-relativ(!!!) schreiben, abspeichern und z.B. mit M2ACODE (von
[fbs]) in INLINE-Statements packen. Wie schon gesagt, für die praktische
Anwendung sind MakeKickRes oder Observer (vollständig in Assembler) viel-
leicht ganz brauchbare Beispiele.
Es ist somit ein Modula-Programm denkbar, das dann irgendeinen Handler
resident installiert, der z.B. auf Tastendruck das Fast-Memory abschaltet,
oder ...
Viel Spaß noch,
Holger